﻿using BlogAppExt.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace BlogAppExt.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// Lists for storing BlogPosts, CommentPosts and Users pointing back to the Singleton
        /// </summary>
        List<BlogPost> posts = Singleton.Instance.BlogPosts;
        List<CommentPost> comments = Singleton.Instance.BlogComments;
        List<User> users = Singleton.Instance.Users;

        /// <summary>
        /// Main index
        /// </summary>
        /// <returns>View with bucket containing list of BlogPosts</returns>
        public ActionResult Index(int id = 0)
        {
            IndexVM bucket = new IndexVM();
            bucket.LoadPosts(posts, users, id);
            //bucket.SetCurrentIndex(id);

            return View(bucket);
        }

        /// <summary>
        /// Action for launching edit on a post
        /// </summary>
        /// <param name="id">ID of the BlogPost to be edited</param>
        /// <returns>View with the post that will be edited</returns>
        [HttpGet]
        public ActionResult EditPost(int id)
        {
            PostDetailVM bucket = new PostDetailVM();
            BlogPost post = posts.Where(x => x.Id == id).FirstOrDefault();

            bucket.LoadPosts(post, users, comments);

            return View(bucket);

        }

        /// <summary>
        /// Action for catching the edited post
        /// </summary>
        /// <param name="postId">ID of the post to be saved</param>
        /// <param name="title">Edited title of the post</param>
        /// <param name="text">Edited text of the post</param>
        /// <returns>Redirect to detail view of the edited post</returns>
        [HttpPost]
        public ActionResult EditPost(int postId, string title, string text)
        {
            BlogPost post = posts.FirstOrDefault(x => x.Id == postId);

            post.Title = title;
            post.Text = text;


            return RedirectToAction("PostDetail", new { id = postId });
        }

        /// <summary>
        /// Action for deleting BlogPost
        /// Also deletes all CommentPosts pointing to the BlogPost
        /// </summary>
        /// <param name="postId">Id of the post to be deleted</param>
        /// <returns>Redirect view back to Index</returns>
        [HttpPost]
        public ActionResult DeletePost(int postId)
        {
            BlogPost post = posts.FirstOrDefault(x => x.Id == postId);
            posts.Remove(post);
            comments.RemoveAll(x => x.ReplyToId == post.Id);

            return RedirectToAction("Index");
        }

        /// <summary>
        /// Action for deleting CommentPost
        /// </summary>
        /// <param name="commentId">Id of the comment to delete</param>
        /// <param name="postId">Id of BlogPost (only used to redirect user back to detail view)</param>
        /// <returns>Redirect view back to the detail view of the BlogPost</returns>
        [HttpPost]
        public ActionResult DeleteComment(int commentId, int postId)
        {
            CommentPost comment = comments.FirstOrDefault(x => x.Id == commentId);
            comments.Remove(comment);

            return RedirectToAction("PostDetail", new { id = postId });
        }

        /// <summary>
        /// Action for viewing a BlogPost in detail
        /// </summary>
        /// <param name="id">Id of the post to view</param>
        /// <returns>Detailed view of the post</returns>
        public ActionResult PostDetail(int id)
        {
            PostDetailVM bucket = new PostDetailVM();
            BlogPost post = posts.Where(x => x.Id == id).FirstOrDefault();

            bucket.LoadPosts(post, users, comments);

            return View(bucket);
        }

        /// <summary>
        /// Launches form for creating a new BlogPost
        /// </summary>
        /// <returns>Form</returns>
        [HttpGet]
        public ActionResult NewPost()
        {

            return View();
        }

        /// <summary>
        /// Creates a new BlogPost
        /// </summary>
        /// <param name="userName">User name of post author</param>
        /// <param name="title">Title of new post</param>
        /// <param name="text">Content of new post</param>
        /// <returns>Detail view of the new post or will direct user to create a new account if the user name does not exist</returns>
        [HttpPost]
        public ActionResult NewPost(string userName, string title, string text)
        {
            User user = users.FirstOrDefault(x => x.UserName == userName);

            if (user == null)
            {
                return RedirectToAction("NewUser");

            }

            BlogPost post = new BlogPost(user.Id, title, text);

            posts.Add(post);

            return RedirectToAction("PostDetail", new { id = post.Id });
        }

        /// <summary>
        /// Launches form for creating a new comment
        /// </summary>
        /// <param name="id">Id of the BlogPost the CommentPost should belong to</param>
        /// <returns>Bucket with the PostDetailVM so user can still see the blog while commenting</returns>
        [HttpGet]
        public ActionResult NewComment(int id)
        {
            PostDetailVM bucket = new PostDetailVM();
            BlogPost post = posts.Where(x => x.Id == id).FirstOrDefault();

            bucket.LoadPosts(post, users, comments);

            return View(bucket);
        }

        /// <summary>
        /// Creates a new comment
        /// </summary>
        /// <param name="postId">Id of the BlogPost the CommentPost should belong to</param>
        /// <param name="userName">User name of the commenter</param>
        /// <param name="text">Content of the comment</param>
        /// <returns>Detail view of the BlogPost</returns>
        [HttpPost]
        public ActionResult NewComment(int postId, string userName, string text)
        {
            User user = users.FirstOrDefault(x => x.UserName == userName);

            if (user == null)
            {
                return RedirectToAction("NewUser");
            }

            CommentPost comment = new CommentPost(postId, user.Id, text);

            comments.Add(comment);

            return RedirectToAction("PostDetail", new { id = postId });
        }

        /// <summary>
        /// Launches form for making a new User
        /// </summary>
        /// <returns>Form fo making new User</returns>
        [HttpGet]
        public ActionResult NewUser()
        {

            return View();
        }

        /// <summary>
        /// Creates a new user
        /// </summary>
        /// <param name="userName">User name (will check if it already exists)</param>
        /// <param name="firstName">First Name</param>
        /// <param name="lastName">Last Name</param>
        /// <param name="image">Image URL</param>
        /// <returns>Redirect back to main index view</returns>
        [HttpPost]
        public ActionResult NewUser(string userName, string firstName, string lastName, string image)
        {
            User user = users.FirstOrDefault(x => x.UserName == userName);

            if (user != null)
            {
                return View();
            }

            users.Add(new User(userName, firstName, lastName, image));

            return RedirectToAction("Index");
        }

        /// <summary>
        /// Runs a search on BlogPosts and CommentPosts
        /// </summary>
        /// <param name="searchString">The string to search for</param>
        /// <returns>The SearchVM with a list of search results</returns>
        [HttpGet]
        public ActionResult Search(string searchString = "")
        {

            SearchVM results = new SearchVM();

            if (searchString == "")
            { return View(results); }

            results.RunSearch(searchString, posts, comments);

            return View(results);
        }

    }
}